package Singleton;

import java.io.Serializable;

/**
 * @Author: 蔡翔
 * @Date: 2019/12/4 9:09
 * @Version 1.0
 * 饿汉式的 单例模式（一开始就实例化好）
 * 有点：因为一开始就实例化好的，类加载的时候就完成了初始化 从而避免了线程同步的问题。
 * 缺点：如果这个类从未用过，那么会造成内存浪费
 */

//Exception in thread "main" java.io.NotSerializableException: Singleton.HungrySingleton ,如果
public class HungrySingleton implements Serializable,Cloneable {
    //类加载的时候就初始化了（不可更改）,,声明为final必须在类加载完成时，就完成赋值。
    private final static HungrySingleton hungrySingleton;
    //静态方法块，初始化 property属性
    static {
        hungrySingleton = new HungrySingleton();
    }

    private HungrySingleton(){
        //写一些 关于反射防御的代码
        if(hungrySingleton !=null){
            throw new RuntimeException("单例构造器禁止反射调用。 ");
        }
    }
    public static HungrySingleton getInstance(){
        //不用判断直接返回，因为在类加载的时候就已经初始化好了。
        return hungrySingleton;
    }

    //一旦我们的业务场景 设计对 对象的序列化和 反序列化，要注意加上这个方法。
    // 一定要要注意序列化和反序列化 对单例的破坏：防止单例被破坏就要加入readResolve() 这个方法。
    //加入下面这行代码，就能使这个单例模式 序列化后 和 反序列后 还能保持相同。
    private Object readResolve(){
        return hungrySingleton;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return getInstance();
    }
}
